package com.jd.service.impl;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.jd.constant.LoginConstant;
import com.jd.entity.User;
import com.jd.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.IncorrectResultSizeDataAccessException;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.jd.constant.LoginConstant.ADMIN_ROLE;

/**
 * @author wangshuping
 * @version 1.0
 * @date 2021/11/15 2:08
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    public static final int USER_TYPE_ENABLED = 1;

    @Autowired
    private UserService userService;


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String loginType = Objects.requireNonNull(requestAttributes).getRequest().getParameter("login_type");
        if (StringUtils.isEmpty(loginType)) {
            throw new AuthenticationServiceException("login_type parameter is required");
        }
        UserDetails userDetails = null;
        try {
            switch (loginType) {
                case LoginConstant.ADMIN_TYPE: // 管理员登录
                    userDetails = loadAdminUserByUsername(username);
                    break;
                case LoginConstant.COMMON_TYPE: //普通用户登录
                    userDetails = loadCommonUserByUsername(username);
                    break;
                default:
                    throw new AuthenticationServiceException("not support login_type" + loginType);
            }
        } catch (IncorrectResultSizeDataAccessException e) {
            throw new UsernameNotFoundException("user：" + username + "not exists");
        }
        return userDetails;

    }

    private UserDetails loadCommonUserByUsername(String username) {
        User user = userService.getCommonUserByUsername(username);
        if (Objects.isNull(user)) {
            throw new UsernameNotFoundException("user：" + username + "not exists");
        }
        return new org.springframework.security.core.userdetails.User(String.valueOf(user.getId()), user.getPassword(), user.getStatus() == USER_TYPE_ENABLED, true, true, true, getUserResources(user.getId()));
    }

    /**
     * 获取用户权限
     * TODO 优化下该代码->管理员逻辑
     *
     * @param userId
     * @return
     */
    private Collection<? extends GrantedAuthority> getUserResources(Long userId) {
        String code = userService.selectRoleCode(userId, ADMIN_ROLE);
        List<String> resourceList = ADMIN_ROLE.equals(code) ? userService.getAllResources() : userService.getResourcesByUserId(userId);
        return resourceList.stream().
                distinct().
                map(SimpleGrantedAuthority::new).
                collect(Collectors.toList());
    }

    private UserDetails loadAdminUserByUsername(String username) {
        return this.loadCommonUserByUsername(username);
    }
}
